<?php

//print_r($_FILES);
//print_r($_SERVER);


    $s = $_GET['s']??'';
    if($s==''){
		die(getFailureJson('s参数不能为空'));
	}
	
	
    $fileName = $_FILES['file']['name'];
    $type = $_FILES['file']['type'];
    $filesize = $_FILES['file']['size'];
    $fileAlias = $_FILES["file"]["tmp_name"];

    if(!$fileAlias){
		die(getFailureJson('上传的文件不存在',-1,$_FILES));
	}
	
	$isLastFile = $_POST['isLastFile'];
		
	$jsonfileInfo = $_POST['jsonfileInfo'];

	$file_info = json_decode($jsonfileInfo,true);
	$md5 = $file_info['md5'];
	$size = $file_info['size'];
	if($md5){
		$inner_dir = $md5.'_'.$size;
	}else{
		$inner_dir = md5($file_info['name']).'_'.$size;
	}
	$each_cut_len = $file_info['each_cut_len'];
	
	if($each_cut_len!=$filesize){
		//die(getFailureJson('上传的文件大小和设定的切割大小不一致',-1,[
		//	'filesize'=>$filesize,
		//	'each_cut_len'=>$each_cut_len,
		//]));
	}
	
	$file_index = $_POST['index'];
	
    //获取当前文件所在的绝对目录
    $dir =  dirname(__FILE__)."/temp_files".'/'.$s.'/'.$inner_dir;
    //files
    mkdirs($dir);
	
	$file_path = $dir."/" . $file_index;
	
	if($_POST['md5']!=''){
		$md5_upload_file = md5_file($fileAlias);
		if($md5_upload_file!=$_POST['md5']){
			die(getFailureJson('文件md5校验失败',-1,[
				'md5_upload_file'=>$md5_upload_file,
				'md5_post'=>$_POST['md5'],
			]));
		}
	}
	
	
	//move_uploaded_file($fileAlias, $file_path);
	
	
	//改成将文件写入占位文件的对应位置，这样最后就不用复制合成文件了
	
	$outputFile = $dir.'/'.'temp_'.$file_info['name'];
	$contentToWrite = file_get_contents($fileAlias);
	$position = $file_index * $each_cut_len;
	fileCoverValAtPos($outputFile,$contentToWrite,$position);
	//然后在原来的数字id文件写一个md5，没有md5就写一个时间戳
	$tempFileValue = $md5;
	if(!$tempFileValue){
		$tempFileValue = time();
	}
	file_put_contents($file_path,$tempFileValue);
	
	
	//检查当前是不是最后一个文件
	if(!$isLastFile){
		die(getSuccessJson('请求成功',[
			
		]));
	}
	
	//计算文件个数
	$file_num = ceil($size/$each_cut_len);
	
	$file_name_key_check_arr = [];
	for($i=0;$i<$file_num;$i++){
		$file_name_key_check_arr[$i]=0;
	}
	
	$temp_file_arr = [];
	$files = scandir($dir);  // 获取文件夹下所有文件和文件夹
	foreach ($files as $file) {
		if (is_numeric($file)) {  // 排除当前目录和上层目录
			$temp_file_arr[]=$file;
			if(isset($file_name_key_check_arr[$file])){
				$file_name_key_check_arr[$file]=1;
			}
		}
	}
	
	$exist_file_name_arr = [];
	$not_exist_file_name_arr = [];
	foreach($file_name_key_check_arr as $file => $exist ){
		if($exist){
			$exist_file_name_arr[]=$file;
		}else{
			$not_exist_file_name_arr[]=$file;
		}
	}
	
	//所有文件都上传完毕，则把文件移动到对应目录
	if(count($not_exist_file_name_arr)==0){
		$outputFile = $dir.'/'.'temp_'.$file_info['name'];
		$targetDir = dirname(__FILE__)."/files".'/'.$s;
		mkdirs($targetDir);
		$targetFile = $targetDir.'/'.$file_info['name'];
		if (rename($outputFile, $targetFile)) {
			//echo "文件移动成功".$targetFile;
		} else {
			die(getFailureJson('文件移动失败',-1,[
				'outputFile'=>$outputFile,
				'targetFile'=>$targetFile,
			]));
		}
		try {
			deleteDirectory($dir);
		} catch (InvalidArgumentException $e) {
			echo "Error: " . $e->getMessage();
		} catch (RuntimeException $e) {
			echo "Error: " . $e->getMessage();
		}
	}
	
	/*
	//如果所有的文件都上传完毕了，则开始合并文件
	if(count($not_exist_file_name_arr)==0){
		//print_r(['exist_file_name_arr'=>$exist_file_name_arr,'not_exist_file_name_arr'=>$not_exist_file_name_arr]);
		// 要合并的文件列表
		 
		// 输出文件
		$outputFile = $dir.'/'.$file_info['name'];
		 
		// 打开输出文件准备写入
		$fp = fopen($outputFile, 'wb');
		 
		// 遍历所有文件，并将它们的内容写入输出文件
		foreach ($exist_file_name_arr as $file) {
			if (file_exists($dir.'/'.$file)) {
				$content = file_get_contents($dir.'/'.$file);
				fwrite($fp, $content);
			}
		}
		 
		// 关闭文件句柄
		fclose($fp);
		
		//计算合并后的文件的md5
		$md5outputFile = md5_file($outputFile);
		if($md5!='' && $md5outputFile!=$md5){
			die(getFailureJson('合并后的文件md5校验失败',-1,[
				'md5outputFile'=>$md5outputFile,
				'md5'=>$md5,
				'name'=>$file_info['name'],
			]));
		}
		$targetFile = dirname(__FILE__)."/files".'/'.$s.'/'.$file_info['name'];
		
		if (rename($outputFile, $targetFile)) {
			//echo "文件移动成功".$targetFile;
		} else {
			die(getFailureJson('文件移动失败',-1,[
				'outputFile'=>$outputFile,
				'targetFile'=>$targetFile,
			]));
		}
		foreach ($exist_file_name_arr as $file) {
			//if (file_exists($dir.'/'.$file)) {
				//unlink($dir.'/'.$file);
			//}
		}
		

		try {
			deleteDirectory($dir);
		} catch (InvalidArgumentException $e) {
			echo "Error: " . $e->getMessage();
		} catch (RuntimeException $e) {
			echo "Error: " . $e->getMessage();
		}
	}
	*/
	
	
	
	die(getSuccessJson('请求成功',[
		
	]));
	
	
	
	//print_r([$_FILES,$_POST,$_GET]);
	//print_r($_POST);
	//print_r($_GET);
	//die;
	//print_r($file_info);
	
	function fileCoverValAtPos($filePath,$contentToWrite,$position){
		$fileSize = 0;
		//文件不存在则创建文件
		if(!file_exists($filePath)){
			//创建一个空文件
			file_put_contents($filePath,'');
		}else{
			//文件存在则获取文件大小
			$fileSize = filesize($filePath);
		}
		
		$each_len =  10 * 1024 * 1024;//分段写入的字节数，暂时设定为3MB，防止内存占用过多
		//需要增加的文件大小
		$fileSizeAdd = $position - $fileSize;
		$fileSizeRemain = $fileSizeAdd;
		//如果文件大小小于写入位置，则填充0到写入位置之前
		if($fileSizeRemain>0){
			// 打开文件，获取文件句柄
			$fileHandle = fopen($filePath, 'a+');
			// 将文件指针移动到指定位置
			//fseek($fileHandle, $fileSize);
			$content = '';
			while($fileSizeRemain>0){
				$writeLen = $each_len;
				if($fileSizeRemain<$each_len){
					$writeLen = $fileSizeRemain;
				}
				// 如果字符串长度不等于要写入的长度，则生成字符串
				if(strlen($content)!=$writeLen){
					$content = str_repeat("0", $writeLen); // 这里使用"0"填充文件，可以根据需要修改
				}
				fwrite($fileHandle, $content);
				$fileSizeRemain = $fileSizeRemain - $writeLen;
			}
			// 写入内容
			fwrite($fileHandle, $contentToWrite);
			// 关闭文件句柄
			fclose($fileHandle);
		}
		//然后开始写入内容
		
		// 打开文件，获取文件句柄
		$fileHandle = fopen($filePath, 'rb+');
		 
		// 将文件指针移动到指定位置
		fseek($fileHandle, $position);
		 
		// 写入内容
		fwrite($fileHandle, $contentToWrite);
		 
		// 关闭文件句柄
		fclose($fileHandle);
 
	}




function mkdirs($dir, $mode = 0777)
 {
     if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
     if (!mkdirs(dirname($dir), $mode)) return FALSE;
     return @mkdir($dir, $mode);
 } 
 
 
 function deleteDirectory($dirPath) {
    // 检查目录是否存在
    if (!is_dir($dirPath)) {
        throw new InvalidArgumentException("$dirPath is not a directory");
    }

    // 打开目录并遍历其中的内容
    $items = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dirPath, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::CHILD_FIRST
    );

    foreach ($items as $item) {
        // 如果是文件，则删除文件
        if ($item->isDir()) {
            rmdir($item->getRealPath());
        } else {
            unlink($item->getRealPath());
        }
    }

    // 尝试删除目录本身
    if (!rmdir($dirPath)) {
        throw new RuntimeException("Failed to remove directory $dirPath");
    }

    //echo "Directory $dirPath deleted successfully";
}
 
 
     function getJson($params)
    {
        return json_encode($params,JSON_UNESCAPED_UNICODE);
    }

    function getSuccessJson($msg='请求成功',$data=[],$code=1)
    {
        return getJson([
            'msg'=>$msg,
            'code'=>$code,
            'data'=>$data,
        ]);
    }

    function getFailureJson($msg='请求失败',$code=-1,$data=[])
    {
        return getJson([
            'msg'=>$msg,
            'code'=>$code,
            'data'=>$data,
        ]);
    }
 